import angular from 'angular';
import ngSelectTemplate from './ng-select.template.html';

ngSelectDirective.$inject = ['$timeout', '$sce', '$q'];

function ngSelectDirective($timeout, $sce, $q) {
  return {
    restrict: 'E',
    template: ngSelectTemplate,
    scope: {
      options: '=',           // 选项数据数组
      ngModel: '=',           // 双向绑定的值
      multiple: '=?',         // 是否多选
      clearable: '=?',        // 是否显示清空按钮
      searchable: '=?',       // 是否可搜索
      valueField: '@?',       // 值字段名，默认 'id'
      labelField: '@?',       // 标签字段名，默认 'label'
      placeholder: '@?',      // 占位符
      searchPlaceholder: '@?',// 搜索框占位符
      remoteSearch: '&?',     // 远程搜索回调函数
      disabled: '=?'          // 是否禁用
    },
    link: function(scope, element) {
      // 初始化默认值
      scope.valueField = scope.valueField || 'id';
      scope.labelField = scope.labelField || 'label';
      scope.multiple = scope.multiple !== undefined ? scope.multiple : false;
      scope.clearable = scope.clearable !== undefined ? scope.clearable : true;
      scope.searchable = scope.searchable !== undefined ? scope.searchable : false;
      scope.placeholder = scope.placeholder || '请选择';
      scope.disabled = scope.disabled || false;

      // 内部状态
      scope.isOpen = false;
      scope.searchKeyword = '';
      scope.filteredOptions = [];
      scope.selectedItems = [];
      scope.loading = false;
      scope.remoteOptions = null;

      var optionCache = Object.create(null);
      var hasRemoteResults = false;

      function updateOptionCache(options) {
        if (!angular.isArray(options)) {
          return;
        }

        options.forEach(function(option) {
          if (!option) {
            return;
          }

          var value = option[scope.valueField];
          if (value === undefined || value === null) {
            return;
          }

          optionCache[value] = option;
        });
      }

      function getCachedOption(value) {
        if (value === undefined || value === null) {
          return null;
        }

        return optionCache[value] || null;
      }

      function getOptionsForDisplay() {
        if (scope.remoteSearch && hasRemoteResults) {
          return scope.remoteOptions || [];
        }

        return scope.options || [];
      }

      // 初始化选中项
      function initSelectedItems() {
        if (scope.ngModel === undefined || scope.ngModel === null) {
          scope.selectedItems = [];
          return;
        }

        if (scope.multiple) {
          if (angular.isArray(scope.ngModel)) {
            var nextSelected = [];

            scope.ngModel.forEach(function(value) {
              var cached = getCachedOption(value);

              if (cached) {
                nextSelected.push(cached);
                return;
              }

              if (value === undefined || value === null) {
                return;
              }

              var fallback = {};
              fallback[scope.valueField] = value;
              fallback[scope.labelField] = value;
              optionCache[value] = fallback;
              nextSelected.push(fallback);
            });

            scope.selectedItems = nextSelected;
          } else {
            scope.selectedItems = [];
          }
        } else {
          var value = scope.ngModel;
          var selectedOption = getCachedOption(value);

          if (!selectedOption && value !== undefined && value !== null) {
            selectedOption = {};
            selectedOption[scope.valueField] = value;
            selectedOption[scope.labelField] = value;
            optionCache[value] = selectedOption;
          }

          scope.selectedItems = selectedOption ? [selectedOption] : [];
        }
      }

      // 过滤选项
      function filterOptions() {
        var options = getOptionsForDisplay();

        if (!angular.isArray(options)) {
          scope.filteredOptions = [];
          return;
        }

        updateOptionCache(options);

        var keyword = scope.searchKeyword ? scope.searchKeyword.toLowerCase() : '';
        var shouldBypassLocalFilter = scope.remoteSearch && hasRemoteResults;

        if (!keyword || shouldBypassLocalFilter) {
          scope.filteredOptions = angular.copy(options);
          return;
        }

        scope.filteredOptions = options.filter(function(option) {
          var label = (option[scope.labelField] || '').toLowerCase();
          return label.indexOf(keyword) !== -1;
        });
      }

      // 打开下拉菜单
      scope.openDropdown = function() {
        if (scope.disabled) return;
        scope.isOpen = true;
        filterOptions();

        if (scope.remoteSearch && !hasRemoteResults && (!scope.options || !scope.options.length)) {
          executeRemoteSearch();
        }
      };

      // 切换下拉菜单
      scope.toggleDropdown = function($event) {
        if (scope.disabled) return;
        $event.stopPropagation();
        scope.isOpen = !scope.isOpen;

        if (scope.isOpen) {
          filterOptions();
          // 聚焦搜索框
          $timeout(function() {
            var searchInput = element[0].querySelector('.ng-select-search-input');
            if (searchInput && scope.searchable) {
              searchInput.focus();
            }
          }, 100);

          if (scope.remoteSearch && !hasRemoteResults && (!scope.options || !scope.options.length)) {
            executeRemoteSearch();
          }
        }
      };

      // 关闭下拉菜单
      function closeDropdown() {
        scope.isOpen = false;
        scope.searchKeyword = '';
        clearHighlightCache();

        if (scope.remoteSearch) {
          hasRemoteResults = false;
          scope.remoteOptions = null;
        }
      }

      // 判断选项是否被选中
      scope.isSelected = function(option) {
        if (!option) return false;

        return scope.selectedItems.some(function(item) {
          return item[scope.valueField] === option[scope.valueField];
        });
      };

      // 选择选项
      scope.selectOption = function(option, $event) {
        if ($event) {
          $event.stopPropagation();
        }

        if (scope.disabled) return;
        if (option.disabled) return;

        var value = option[scope.valueField];
        if (value === undefined || value === null) {
          return;
        }

        updateOptionCache([option]);
        var resolvedOption = getCachedOption(value) || option;

        if (scope.multiple) {
          // 多选模式
          var index = scope.selectedItems.findIndex(function(item) {
            return item[scope.valueField] === value;
          });

          if (index !== -1) {
            // 已选中，取消选中
            scope.selectedItems.splice(index, 1);
          } else {
            // 未选中，添加选中
            scope.selectedItems.push(resolvedOption);
          }

          // 更新 ngModel
          scope.ngModel = scope.selectedItems.map(function(item) {
            return item[scope.valueField];
          });
        } else {
          // 单选模式
          scope.selectedItems = [resolvedOption];
          scope.ngModel = resolvedOption[scope.valueField];
          closeDropdown();
        }
      };

      // 移除单个选项（多选模式）
      scope.removeItem = function(item, $event) {
        if ($event) {
          $event.stopPropagation();
        }

        if (!scope.multiple || scope.disabled) return;

        var index = scope.selectedItems.indexOf(item);
        if (index !== -1) {
          scope.selectedItems.splice(index, 1);

          // 更新 ngModel
          scope.ngModel = scope.selectedItems.map(function(item) {
            return item[scope.valueField];
          });
        }
      };

      // 清空选择
      scope.clearSelection = function($event) {
        if ($event) {
          $event.stopPropagation();
        }

        if (scope.disabled) return;

        scope.selectedItems = [];
        scope.ngModel = scope.multiple ? [] : null;
        scope.searchKeyword = '';
        clearHighlightCache();
        filterOptions();
      };

      // 高亮搜索文本
      var highlightCache = {};
      scope.highlightText = function(text) {
        if (!text) {
          return text;
        }

        if (!scope.searchKeyword) {
          return text;
        }

        // 使用缓存避免重复计算
        var cacheKey = scope.searchKeyword + '::' + text;
        if (highlightCache[cacheKey]) {
          return highlightCache[cacheKey];
        }

        var keyword = scope.searchKeyword;
        var regex = new RegExp('(' + keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + ')', 'gi');
        var highlightedText = text.replace(regex, '<span class="search-highlight">$1</span>');
        var result = $sce.trustAsHtml(highlightedText);

        highlightCache[cacheKey] = result;
        return result;
      };

      // 清除高亮缓存
      function clearHighlightCache() {
        highlightCache = {};
      }

      // 搜索防抖
      var searchTimeout;

      // 处理搜索
      scope.handleSearch = function() {
        // 清除之前的延时
        if (searchTimeout) {
          $timeout.cancel(searchTimeout);
        }

        clearHighlightCache();
        var keyword = scope.searchKeyword ? scope.searchKeyword.trim() : '';

        // 如果有远程搜索函数，使用远程搜索
        if (scope.remoteSearch) {
          if (!keyword) {
            hasRemoteResults = false;
            scope.remoteOptions = null;
            filterOptions();
          }

          searchTimeout = $timeout(function() {
            executeRemoteSearch();
          }, 300);
        } else {
          // 本地搜索
          searchTimeout = $timeout(function() {
            filterOptions();
          }, 150);
        }
      };

      // 执行远程搜索
      function executeRemoteSearch() {
        var keyword = scope.searchKeyword ? scope.searchKeyword.trim() : '';

        scope.loading = true;
        hasRemoteResults = false;

        // 调用远程搜索回调
        var result = scope.remoteSearch({ keyword: keyword });

        // 处理 Promise
        $q.when(result).then(function(data) {
          scope.loading = false;

          var normalized = [];
          if (angular.isArray(data)) {
            normalized = data;
          } else if (data && angular.isArray(data.items)) {
            normalized = data.items;
          } else if (data && angular.isArray(data.data)) {
            normalized = data.data;
          }

          hasRemoteResults = true;
          scope.remoteOptions = normalized;
          updateOptionCache(normalized);
          initSelectedItems();
          filterOptions();
        }).catch(function(error) {
          scope.loading = false;
          hasRemoteResults = false;
          scope.remoteOptions = [];
          scope.filteredOptions = [];
          console.error('Remote search error:', error);
        });
      }

      // 监听 options 变化
      scope.$watch('options', function(newVal) {
        hasRemoteResults = false;
        scope.remoteOptions = null;

        if (angular.isArray(newVal)) {
          updateOptionCache(newVal);
        }

        initSelectedItems();

        if (!scope.remoteSearch || !hasRemoteResults) {
          filterOptions();
        }
      }, true);

      // 监听 ngModel 变化
      scope.$watch('ngModel', function() {
        initSelectedItems();
      }, true);

      // 点击外部关闭下拉菜单
      var documentClickHandler = function(event) {
        var isClickInside = element[0].contains(event.target);
        if (!isClickInside && scope.isOpen) {
          scope.$apply(function() {
            closeDropdown();
          });
        }
      };

      angular.element(document).on('click', documentClickHandler);

      // 清理事件监听
      scope.$on('$destroy', function() {
        angular.element(document).off('click', documentClickHandler);
        if (searchTimeout) {
          $timeout.cancel(searchTimeout);
        }
      });

      // 初始化
      updateOptionCache(scope.options);
      initSelectedItems();
      filterOptions();
    }
  };
}

export default ngSelectDirective;
